<?php
namespace lib\http;

class Session
{
    private $redis;
    private $session_id;

    public static $instance=null;
    public static function Instance()
    {
        if(!self::$instance)
        {
            $sid=self::CreateSid();
            self::$instance=new Session($sid);
        }
        return self::$instance;
    }

    public static function Start()
    {
        $GLOBALS['session']=self::Instance();
    }

    public static function CreateSid()
    {
        $session_id=$_COOKIE['bbb'];
        if (!$session_id)
        {
            $session_id=md5($_SERVER['REMOTE_ADDR'].strval(microtime(true)));
            setcookie('bbb',$session_id,time()+3600*24,'/','',false,true);
        }
        return $session_id;
    }

    public static function Destroy()
    {
        if(!self::$instance) return false;

        unset($_SESSION);
        self::$instance->delete(self::$instance->session_id);
    }

    private function __construct($session_id)
    {
        $this->redis=new \Redis();
        $this->redis->connect("127.0.0.1",6379);
        $this->redis->select(0);
        $this->redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP);

        $this->session_id='sess_'.$session_id;

        $_SESSION=$this->redis->get($this->session_id);
        if(!$_SESSION)
        {
            $_SESSION=array();
        }
    }

    public function read($key)
    {
        return $_SESSION[$key];
    }

    public function write($key,$value)
    {
        $_SESSION[$key]=$value;
    }

    public function __destruct()
    {
        if($_SESSION)
        {
            $this->redis->set($this->session_id,$_SESSION,600);
        }
        $this->redis->close();
    }

    public function __invoke($key,$value=false)
    {
        if($value===false)
        {
            return $_SESSION[$key];
        }
        else
        {
            $_SESSION[$key]=$value;
        }
    }
    public function __call($name, $arguments)
    {
        if(!method_exists($this->redis,$name))
        {
            echo "$name not exist";
            exit;
        }

        return call_user_func_array(
            array($this->redis,$name),
            $arguments
        );



    }

}
